/*
 * Implementação de um programa que realiza etiquetagem em um segmento
 * de texto dado com base em informações prévias em forma de tabelas de
 * referência usando o algoritmo genético.
 * Autor: Leonardo Hirokazu de Souza Hamada, 17 de junho de 2014.
*/

#include "etiq-ag.h"

int main(int argc, char **argv)
{
    // Instanciando as tabelas necessárias.
    GNA = new Rand();
    QUADRO_DE_ABREV_DAS_ETIQUETAS = new std::vector<std::string>;
    QUADRO_DE_FREQ_DAS_ETIQUETAS = new std::vector<std::size_t>;
    TABELA_NUMERICA_ETIQUETAS = new std::map<std::string,TIPO_GENE>;

    // Alimentando o conjunto de etiquetas do corpus
    std::fstream ar;
    char buf[1024*64]  = "";
    ar.open("tabelas/extracao_etiquetas.txt", std::fstream::in);
    if (ar.rdstate() & std::fstream::failbit) {
        std::cout << "Não foi encontrado o arquivo tabelas/extracao_etiquetas.txt." << std::endl;
        exit(1);
    }
    TIPO_GENE indice = 0;
    TotalEtiquetaCorpus = 0;
    while (ar.getline(buf, 1024*64)) {
        std::istringstream etq_freq_ss(buf);
        std::string str_abv;
        etq_freq_ss >> str_abv;
        std::size_t freq_etq;
        etq_freq_ss >> freq_etq;
        TotalEtiquetaCorpus += freq_etq;
        (*QUADRO_DE_FREQ_DAS_ETIQUETAS).push_back(freq_etq);
        (*QUADRO_DE_ABREV_DAS_ETIQUETAS).push_back(str_abv);
        (*TABELA_NUMERICA_ETIQUETAS)[str_abv] = indice;
	if (indice >= 255) {
        	std::cout << "O limite do conjunto de etiquetas de 255 foi atingida." << std::endl;
        	exit(1);
	}
	++indice;
    }
    ar.close();

    std::size_t N = 40;    // pares, tam. população entre 20 e 30 indiv
    double pc = 0.9;     // taxa de cruz. entre 0,75 e 0,95
    double pm = 0.1;     // taxa de mut. entre 0,005 e 0,01
    std::size_t ng = 80;// 100 - 500  nro. gerações
    std::vector<std::string> seg;
    std::string texto = "Pesquisa divulgada ontem mostra que 24 % de os alemães acham que as idéias de Hitler não eram assim tão ruins";
    std::string nome_arquivo_entrada = "";
    for (int op = 1; op < argc - 1; op+=2) {
        std::string opcao(argv[op]);
        if (opcao == "-N") {
            std::istringstream(argv[op+1]) >> N;
            continue;
        }
        if (opcao == "-pc") {
            std::istringstream(argv[op+1]) >> pc;
            continue;
        }
        if (opcao == "-pm") {
            std::istringstream(argv[op+1]) >> pm;
            continue;
        }
        if (opcao == "-ng") {
            std::istringstream(argv[op+1]) >> ng;
            continue;
        }
        if (opcao == "-seg") {
            texto = argv[op+1];
            continue;
        }
        if (opcao == "-ar") {
            nome_arquivo_entrada = argv[op+1];
            continue;
        }
        std::cout << "Opção desconhecida" << std::endl;
        exit(1);
    }
#if DEPURAR
    std::cout<< "N,pc,pm,ng = " << N << " " << pc << " " << pm << " " << ng <<  " " << std::endl;
    std::cout<< "Segmento: " << texto << std::endl;
#endif
    SGA sga;
    if (nome_arquivo_entrada != "") {
        ar.open(nome_arquivo_entrada, std::fstream::in);
        if (ar.rdstate() & std::fstream::failbit) {
            std::cout << "Não foi encontrado o arquivo de entrada " << nome_arquivo_entrada << std::endl;
            exit(1);
        }
        while (ar.getline(buf, 1024*64)) {
            seg.clear();
            std::istringstream linhaTexto(buf);
            do {
                std::string palavra;
                if ((!(linhaTexto >> palavra)) || (palavra == "")) break;
                seg.push_back(palavra);
            } while(1);
            if (seg.empty()) {
                std::cout << "Não existem palavras a serem etiquetadas." << std::endl;
                exit(1);
            }
            sga.fazerNovoPreparativo(seg, N);
            sga.evoluir(ng, pc, pm);
        }
        ar.close();
    } else {
        seg.clear();
        std::istringstream linhaTexto(texto);
        do {
            std::string palavra;
            if ((!(linhaTexto >> palavra)) || (palavra == "")) break;
            seg.push_back(palavra);
        } while(1);
        if (seg.empty()) {
            std::cout << "Não existem palavras a serem etiquetadas." << std::endl;
            exit(1);
        }
        sga.fazerNovoPreparativo(seg, N);
        sga.evoluir(ng, pc, pm);
    }
    delete GNA;
    delete QUADRO_DE_ABREV_DAS_ETIQUETAS;
    delete TABELA_NUMERICA_ETIQUETAS;
    delete QUADRO_DE_FREQ_DAS_ETIQUETAS;
}
